import React, { useState, useCallback, useEffect, useRef, useContext } from 'react';
import { cn } from '../helpers/utils';
import GanttContext from '../context';
import { GanttConsts } from '../constants';

interface VirtualScrollbarProps {
  // 垂直滚动相关
  totalHeight?: number;
  // 水平滚动相关
  totalWidth?: number;
  // 通用属性
  direction?: 'vertical' | 'horizontal' | 'both';
  className?: string;
  style?: React.CSSProperties;
}

const VirtualScrollbar: React.FC<VirtualScrollbarProps> = ({
  totalHeight = 0,
  totalWidth = 0,
  direction = 'vertical',
  className = '',
  style = {},
}) => {
  const [isDraggingY, setIsDraggingY] = useState(false);
  const [isDraggingX, setIsDraggingX] = useState(false);
  const [dragStartY, setDragStartY] = useState(0);
  const [dragStartX, setDragStartX] = useState(0);
  const [dragStartScrollTop, setDragStartScrollTop] = useState(0);
  const [dragStartScrollLeft, setDragStartScrollLeft] = useState(0);
  const vScrollbarRef = useRef<HTMLDivElement>(null);
  const hScrollbarRef = useRef<HTMLDivElement>(null);
  const { scrollTop, setScrollTop, scrollLeft, setScrollLeft, containerHeight, containerWidth, hideTask } = useContext(GanttContext);

  // 垂直滚动条计算
  const ganttTableContainerHeight = containerHeight - GanttConsts.HEADER_HEIGHT - GanttConsts.HEAD_HEIGHT;
  const ganttTableContainerWidth = containerWidth - (hideTask ? 0 : (GanttConsts.TASK_WIDTH + GanttConsts.SPLIT_WIDTH));
  const maxScrollTop = Math.max(0, totalHeight - ganttTableContainerHeight);
  const showVScrollbar = (direction === 'vertical' || direction === 'both') && totalHeight > ganttTableContainerHeight;

  // 安全计算垂直滚动条高度，避免Infinity和NaN
  const vScrollbarHeight = totalHeight > 0 && ganttTableContainerHeight > 0
    ? Math.max((ganttTableContainerHeight / totalHeight) * ganttTableContainerHeight, 20)
    : 20;

  // 安全计算垂直滚动条位置，避免NaN
  const vScrollbarTop = Math.max(0, (maxScrollTop > 0 && vScrollbarHeight
    ? (scrollTop / maxScrollTop) * (ganttTableContainerHeight - vScrollbarHeight)
    : 0) - GanttConsts.BAR_SIZE);

  // 水平滚动条计算
  const maxScrollLeft = Math.max(0, totalWidth - ganttTableContainerWidth);
  const showHScrollbar = (direction === 'horizontal' || direction === 'both') && totalWidth > ganttTableContainerWidth;

  // 安全计算水平滚动条宽度，避免Infinity和NaN
  const hScrollbarWidth = totalWidth > 0 && ganttTableContainerWidth > 0
    ? Math.max((ganttTableContainerWidth / totalWidth) * ganttTableContainerWidth, 20)
    : 20;

  // 安全计算水平滚动条位置，避免NaN
  const hScrollbarLeft = Math.max(0, (maxScrollLeft > 0 && hScrollbarWidth
    ? (scrollLeft / maxScrollLeft) * (ganttTableContainerWidth - hScrollbarWidth)
    : 0) - GanttConsts.BAR_SIZE);

  // 处理垂直滚动条拖拽开始
  const handleVScrollbarMouseDown = useCallback((e: React.MouseEvent) => {
    e.preventDefault();
    setIsDraggingY(true);
    setDragStartY(e.clientY);
    setDragStartScrollTop(scrollTop);
  }, [scrollTop]);

  // 处理水平滚动条拖拽开始
  const handleHScrollbarMouseDown = useCallback((e: React.MouseEvent) => {
    e.preventDefault();
    setIsDraggingX(true);
    setDragStartX(e.clientX);
    setDragStartScrollLeft(scrollLeft);
  }, [scrollLeft]);

  // 使用useRef来存储最新的值，避免频繁重新创建handleMouseMove
  const dragStateRef = useRef({
    isDraggingY: false,
    isDraggingX: false,
    dragStartY: 0,
    dragStartX: 0,
    dragStartScrollTop: 0,
    dragStartScrollLeft: 0,
    containerHeight: 0,
    containerWidth: 0,
    vScrollbarHeight: 0,
    hScrollbarWidth: 0,
    maxScrollTop: 0,
    maxScrollLeft: 0,
  });

  // 更新ref中的值
  dragStateRef.current = {
    isDraggingY,
    isDraggingX,
    dragStartY,
    dragStartX,
    dragStartScrollTop,
    dragStartScrollLeft,
    containerHeight: ganttTableContainerHeight,
    containerWidth: ganttTableContainerWidth,
    vScrollbarHeight,
    hScrollbarWidth,
    maxScrollTop,
    maxScrollLeft,
  };

  // 处理滚动条拖拽 - 优化版本，减少依赖项
  const handleMouseMove = useCallback((e: MouseEvent) => {
    const state = dragStateRef.current;

    if (state.isDraggingY) {
      const deltaY = e.clientY - state.dragStartY;
      const scrollRatio = deltaY / (state.containerHeight - state.vScrollbarHeight);
      const newScrollTop = Math.max(0, Math.min(state.maxScrollTop, state.dragStartScrollTop + scrollRatio * state.maxScrollTop));
      setScrollTop(newScrollTop);
    }

    if (state.isDraggingX) {
      const deltaX = e.clientX - state.dragStartX;
      const scrollRatio = deltaX / (state.containerWidth - state.hScrollbarWidth);
      const newScrollLeft = Math.max(0, Math.min(state.maxScrollLeft, state.dragStartScrollLeft + scrollRatio * state.maxScrollLeft));
      setScrollLeft(newScrollLeft);
    }
  }, [setScrollTop, setScrollLeft]);

  // 处理拖拽结束
  const handleMouseUp = useCallback(() => {
    setIsDraggingY(false);
    setIsDraggingX(false);
  }, []);

  // 添加全局鼠标事件监听
  useEffect(() => {
    if (isDraggingY || isDraggingX) {
      document.addEventListener('mousemove', handleMouseMove);
      document.addEventListener('mouseup', handleMouseUp);
      return () => {
        document.removeEventListener('mousemove', handleMouseMove);
        document.removeEventListener('mouseup', handleMouseUp);
      };
    }
  }, [isDraggingY, isDraggingX, handleMouseMove, handleMouseUp]);

  if (!showVScrollbar && !showHScrollbar) {
    return null;
  }

  return (
    <>
      {/* 垂直滚动条 */}
      {showVScrollbar && (
        <div
          className={`absolute right-0 transition-colors cursor-pointer z-10 ${className}`}
          style={{ width: `${GanttConsts.BAR_SIZE}px`, height: ganttTableContainerHeight, ...style }}
        >
          <div
            ref={vScrollbarRef}
            className={cn({
              "absolute right-0 top-0 bg-gray-300/60 hover:bg-gray-400/60 rounded transition-colors cursor-grab": true,
              "bg-gray-500/60 cursor-grabbing": isDraggingY,
            })}
            style={{
              height: vScrollbarHeight,
              top: vScrollbarTop,
              width: `${GanttConsts.BAR_SIZE}px`,
            }}
            onMouseDown={handleVScrollbarMouseDown}
          />
        </div>
      )}

      {/* 水平滚动条 */}
      {showHScrollbar && (
        <div
          className={`absolute bottom-0 transition-colors cursor-pointer z-10 ${className}`}
          style={{ height: `${GanttConsts.BAR_SIZE}px`, width: ganttTableContainerWidth, ...style }}
        >
          <div
            ref={hScrollbarRef}
            className={cn({
              "absolute bottom-0 left-0 bg-gray-300/60 hover:bg-gray-400/60 rounded transition-colors cursor-grab": true,
              "bg-gray-500/60 cursor-grabbing": isDraggingX,
            })}
            style={{
              width: hScrollbarWidth,
              left: hScrollbarLeft,
              height: `${GanttConsts.BAR_SIZE}px`,
            }}
            onMouseDown={handleHScrollbarMouseDown}
          />
        </div>
      )}
    </>
  );
};

export default VirtualScrollbar;